#include "openhash.h"
using namespace hashtable;

OpenHashTable::OpenHashTable(int s)
{
    this->m_data = new ValuePair[s];
    for (int i = 0; i < s; ++i)
    {
        this->m_data[i].m_use = false;
    }
    this->m_cap = s;
    this->m_size = 0;
}

void OpenHashTable::OhtblInsert(int k, int d)
{
    if (this->m_cap == this->m_size)
    {
        return;
    }

    int t = 0;
    if (this->OhtblLookup(k, t))
    {
        return;
    }

    for (int i = 0; i < this->m_cap; ++i)
    {
        t = this->HashKey(k, i);
        if (this->m_data[t].m_use == false)
        {
            this->m_data[t].m_key = k;
            this->m_data[t].m_data = d;
            this->m_data[t].m_use = true;
            ++this->m_size;
            return;
        }
    }
}

void OpenHashTable::OhtblDel(int k)
{
     int idx = 0;
     for (int i = 0; i < this->m_cap; ++i)
     {
         idx = this->HashKey(k, i);
         if ((this->m_data[idx].m_use == true) &&(this->m_data[idx].m_key == k))
         {
             this->m_data[idx].m_use = false;
             --this->m_size;
             return;
         }
     }
}

bool OpenHashTable::OhtblLookup(int k, int& d)
{
    int idx = 0;
    for (int i = 0; i < this->m_cap; ++i)
    {
         idx = this->HashKey(k, i);
         if ((this->m_data[idx].m_use == true) &&(this->m_data[idx].m_key == k))
         {
             d = this->m_data[idx].m_data;
             return true;
         }
    }

    return false;
}

int OpenHashTable::GetHashSize()
{
    return this->m_size;
}

int OpenHashTable::HashKey(int k, int i)
{
    return (this->HashKeyHelper1(k) + i*this->HashKeyHelper2(k))%this->m_cap;
}

int OpenHashTable::HashKeyHelper1(int k)
{
    return k%this->m_cap;
}

int OpenHashTable::HashKeyHelper2(int k)
{
     return 1 + k%(this->m_cap-1);
}
